package pl.edu.agh.jemo.evolution.objfunc.impl.clustering;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import pl.edu.agh.jemo.evolution.objfunc.ICrowdingObjectiveFunction;
import pl.edu.agh.jemo.evolution.objfunc.impl.PopulationCentroidObjectiveFunction;
import pl.edu.agh.jemo.evolution.population.IPopulation;
import pl.edu.agh.jemo.evolution.population.impl.Population;
import pl.edu.agh.jemo.evolution.specimen.ISpecimen;

public class ClusteringObjectiveFunction implements ICrowdingObjectiveFunction {

	protected IPopulation population;
	private Map<ISpecimen, Window> clusterSpecimenMap;
	private Map<ISpecimen, Double> centroidValues;
	
	public ClusteringObjectiveFunction() {
	}
	
	@Override
	public void setPopulationReference(IPopulation population) {
		this.population = population;
		clusterSpecimenMap = null;
	}

	@Override
	public Double calculateValue(ISpecimen specimen) {
		if (clusterSpecimenMap == null) {
			clusterSpecimenMap = (new Clusterizer()).clusterize(population);
			centroidValues = new HashMap<ISpecimen, Double>();
			for(Window w : clusterSpecimenMap.values()) {
				if (w==null) continue;
				IPopulation pop = new Population();
				pop.addAll(w.getSpecimensInside());
				PopulationCentroidObjectiveFunction fun = new PopulationCentroidObjectiveFunction();
				fun.setPopulationReference(pop);
				
				for(ISpecimen s : pop) {
					centroidValues.put(s, fun.calculateValue(s));
				}
			}
		}
		if (clusterSpecimenMap.get(specimen) == null)
			return 0.0;

		return centroidValues.get(specimen);
	}

	@Override
	public List<List<Double>> getBoundaries() {
		return null;
	}

	@Override
	public int getDimensions() {
		return 2;
	}

	@Override
	public String getFormula() {
		return null;
	}

	@Override
	public boolean isInDomain(ISpecimen specimen) {
		return true;
	}

}
